#include "jsonrpcservice.h"


#include <QRegularExpression>
#include <QStringList>
#include <QJsonDocument>
#include <QTcpSocket>
#include <QMetaClassInfo>
#include <QMetaMethod>



JsonRpcService::JsonRpcService() : QObject()
{
}



JsonRpcMessage::ErrorCode JsonRpcService::invokeSlot(QObject *instance, const QString& methodName, const QVariantList& params, QVariant& returnValue){
    const QMetaObject *meta = instance->metaObject();
    int idx = meta->indexOfMethod(methodName.toLatin1().constData());

    if(idx == -1){
        return JsonRpcMessage::MethodNotFound;
    }
    QMetaMethod metaMethod = meta->method(idx);
    int paramsCount = metaMethod.parameterCount();
    if(params.count() != paramsCount){
        return JsonRpcMessage::DifferentSignature;
    }
    int returnType = metaMethod.returnType();

    QList<int> paramTypes;

    paramTypes.append(returnType);
    for(int i=0; i<paramsCount; i++){
        paramTypes.append(metaMethod.parameterType(i));
    }
    void **paramsArray = new void *[paramTypes.count()];

    // Return type
    paramsArray[0] = QMetaType::create(paramTypes.at(0));
    QVariant value;
    for(int i=1; i<paramTypes.count(); i++){
        value = params.at(i-1);
        value.convert(paramTypes.at(i));
        paramsArray[i] = QMetaType::create(paramTypes.at(i), value.constData());
    }

    meta->metacall(instance, QMetaObject::InvokeMetaMethod, idx, paramsArray);

    if(returnType == QMetaType::Void){
        returnValue = QVariant();
    }else{
        returnValue = QVariant(returnType, paramsArray[0]);
    }

    for(int i=0; i<paramTypes.count(); i++){
        QMetaType::destroy(paramTypes.at(i), paramsArray[i]);
    }
    delete[] paramsArray;

    return JsonRpcMessage::NoError;
}

